package com.yjymm.edu.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yjymm.edu.common.MyBeanUtils;
import com.yjymm.edu.common.OSSUtils;
import com.yjymm.edu.common.RedisUtils;
import com.yjymm.edu.common.StringUtils;
import com.yjymm.edu.common.component.OSSComponent;
import com.yjymm.edu.mapper.*;
import com.yjymm.edu.model.common.RoleEnum;
import com.yjymm.edu.model.dto.SearchOrderDTO;
import com.yjymm.edu.model.dto.SearchTeacherDTO;
import com.yjymm.edu.model.dto.SearchUserDTO;
import com.yjymm.edu.model.entity.OrderTable;
import com.yjymm.edu.model.entity.Role;
import com.yjymm.edu.model.entity.User;
import com.yjymm.edu.model.vo.OrderVO;
import com.yjymm.edu.model.vo.UserVO;
import com.yjymm.edu.service.OrderTableService;
import com.yjymm.edu.service.SearchService;
import com.yjymm.edu.service.UgtableService;
import com.yjymm.edu.service.UstableService;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author yjymm
 * @date 2021-01-05 17:25
 */

@Service
public class SearchServiceImpl implements SearchService {

    @Resource
    private UserMapper userMapper;
    @Resource
    private RoleMapper roleMapper;
    @Resource
    private UstableMapper ustableMapper;
    @Resource
    private UgtableMapper ugtableMapper;

    @Resource
    private UgtableService ugtableService;

    @Resource
    private UstableService ustableService;

    @Resource
    private RedisUtils redisUtils;

    @Resource
    private OrderTableMapper orderTableMapper;

    @Resource
    private OrderTableService orderTableService;

    @Resource
    private OSSComponent ossComponent;

    @Resource
    private OSSUtils ossUtils;


    /**
     * 对家教老师进行搜索
     *
     * @param searchTeacherDTO
     * @return
     */
    @Override
    public IPage search(SearchTeacherDTO searchTeacherDTO) {
        // 未带有感兴趣的年级和科目
        if (CollectionUtils.isEmpty(searchTeacherDTO.getGradeIds()) && CollectionUtils.isEmpty(searchTeacherDTO.getSubjectIds())) {
            return searchTeacherWithTeacherName(searchTeacherDTO.getPage(), searchTeacherDTO.getSize(), searchTeacherDTO.getTeacherName());
        }
        // 查询所有角色为教师的uid
        User user = new User();
        user.setRoleId(RoleEnum.TEACHER.getId());
        user.setUsername(StringUtils.isBlank(searchTeacherDTO.getTeacherName()) ? null : searchTeacherDTO.getTeacherName());
        user.setDeleted(0);
        List<Integer> uidList = userMapper.selectWithProp(user);
        List<Integer> sutiable = findSutiable(uidList, searchTeacherDTO);
        if (CollectionUtils.isEmpty(sutiable)) {
            return null;
        }
        // 如果对teacherName进行模糊查询
        if (!StringUtils.isBlank(searchTeacherDTO.getTeacherName())) {
            List<Integer> ids = userMapper.findUserIdsWithTeacherName(searchTeacherDTO.getTeacherName(), sutiable);
            sutiable = ids;
        }

        // 先进行uid排序，然后对所有结果进行分页
        Collections.sort(sutiable);
        // 分页
        // fromIndex 包含
        int fromIndex = (int) ((searchTeacherDTO.getPage() - 1) * searchTeacherDTO.getSize());
        // 判断fromIndex是否月结
        if (fromIndex > sutiable.size() - 1) {
            IPage<UserVO> page = new Page<>(searchTeacherDTO.getPage(), searchTeacherDTO.getSize());
            page.setRecords(null);
            page.setTotal(sutiable.size());
            return page;
        }
        // toIndex不包含
        int toIndex = (int) (fromIndex + searchTeacherDTO.getSize());
        if (toIndex > sutiable.size()) {
            toIndex = sutiable.size();
        }

        List<Integer> pageList = sutiable.subList(fromIndex, toIndex);

        // 批量查询用户信息并返回
        List<User> users = userMapper.selectBatchIds(pageList);
        List<UserVO> userVOS = MyBeanUtils.converToList(users, UserVO.class);
        IPage<UserVO> page = new Page<>(searchTeacherDTO.getPage(), searchTeacherDTO.getSize());

        page.setRecords(userVOS);
        page.setTotal(sutiable.size());
        setAvatar(userVOS);
        return page;
    }

    /**
     * 查询所有教师，分页
     *
     * @return
     */
    @Override
    public IPage searchTeacherWithTeacherName(long pageN, long size, String teacherName) {
        IPage<User> page = new Page<>(pageN, size);

        // TODO: 2021/3/31 查询条件有待查看文档验证
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("role_id", RoleEnum.TEACHER.getId());
        if (!StringUtils.isBlank(teacherName)) {
            queryWrapper.and((x)->{
                return x.like(!StringUtils.isBlank(teacherName), "username", teacherName)
                        .or()
                        .like(!StringUtils.isBlank(teacherName), "real_name", teacherName);
            });
        }
        page = userMapper.selectPage(page, queryWrapper);
        IPage<UserVO> page1 = new Page<>(pageN, size);
        page1.setPages(page.getPages());
        page1.setTotal(page.getTotal());
        List<UserVO> userVOS = MyBeanUtils.converToList(page.getRecords(), UserVO.class);
        page1.setRecords(userVOS);
        setAvatar(userVOS);
        return page1;
    }

    /**
     * 查找符合条件的所有教师id
     *
     * @param uidList
     * @param searchTeacherDTO
     * @return
     */
    private List<Integer> findSutiable(List<Integer> uidList, SearchTeacherDTO searchTeacherDTO) {
        Boolean findWihtGrade = CollectionUtils.isEmpty(searchTeacherDTO.getGradeIds()) ? Boolean.FALSE : Boolean.TRUE;
        Boolean findWithSubject = CollectionUtils.isEmpty(searchTeacherDTO.getSubjectIds()) ? Boolean.FALSE : Boolean.TRUE;

        if (findWihtGrade && findWithSubject) {
            return doFindSutiable(uidList, searchTeacherDTO);
        } else if (findWihtGrade && !findWithSubject) {
            return doFindSutiableGrade(uidList, searchTeacherDTO);
        } else {
            return doFindSutiableSubject(uidList, searchTeacherDTO);
        }
    }

    public List<Integer> doFindSutiable(List<Integer> uidList, SearchTeacherDTO searchTeacherDTO) {
        List<Integer> list = new ArrayList<>();
        for (Integer uid : uidList) {
            List<Integer> userFarvoriteGradeIds = ugtableService.getUserFarvoriteGradeIds(uid);
            List<Integer> userFarvoriteSubjectIds = ustableService.getUserFarvoriteSubjectIds(uid);

            // 教师的兴趣年级和科目都未空，直接添加
            if (CollectionUtils.isEmpty(userFarvoriteSubjectIds) && CollectionUtils.isEmpty(userFarvoriteSubjectIds)) {
                list.add(uid);
                continue;
            }

            // 教师的兴趣科目不为空
            if (!CollectionUtils.isEmpty(userFarvoriteSubjectIds)) {
                List<Integer> subjectIds = searchTeacherDTO.getSubjectIds();
                for (Integer subjectId : subjectIds) {
                    if (userFarvoriteSubjectIds.contains(subjectId)) {
                        list.add(uid);
                        break;
                    }
                }
                continue;
            }

            // 教师的兴趣年级不为空
            if (!CollectionUtils.isEmpty(userFarvoriteGradeIds)) {
                List<Integer> gradeIds = searchTeacherDTO.getGradeIds();
                for (Integer gradeId : gradeIds) {
                    if (userFarvoriteGradeIds.contains(gradeId)) {
                        list.add(uid);
                        break;
                    }
                }
                continue;
            }

            List<Integer> gradeIds = searchTeacherDTO.getGradeIds();
            List<Integer> subjectIds = searchTeacherDTO.getSubjectIds();
            boolean flag = false;
            for (Integer gradeId : gradeIds) {
                for (Integer subjectId : subjectIds) {
                    if (userFarvoriteGradeIds.contains(gradeId) && userFarvoriteSubjectIds.contains(subjectId)) {
                        list.add(uid);
                        flag = true;
                        break;
                    }
                }
                if (flag) break;
            }
        }
        List<Integer> collect = list.stream().distinct().collect(Collectors.toList());
        return collect;
    }

    public List<Integer> doFindSutiableGrade(List<Integer> uidList, SearchTeacherDTO searchTeacherDTO) {
        List<Integer> list = new ArrayList<>();
        for (Integer uid : uidList) {
            List<Integer> userFarvoriteGradeIds = ugtableService.getUserFarvoriteGradeIds(uid);
            if(CollectionUtils.isEmpty(userFarvoriteGradeIds)) {
                list.add(uid);
                continue;
            }
            List<Integer> gradeIds = searchTeacherDTO.getGradeIds();
            for (Integer gradeId : gradeIds) {
                if (userFarvoriteGradeIds.contains(gradeId)) {
                    list.add(uid);
                    break;
                }
            }
        }
        List<Integer> collect = list.stream().distinct().collect(Collectors.toList());
        return collect;
    }

    private void setAvatar(List<UserVO> userVOS) {
        for (UserVO userVO : userVOS) {
            userVO.setAvatar(ossUtils.addUrlPrefix(userVO.getAvatar()));
        }
    }

    public List<Integer> doFindSutiableSubject(List<Integer> uidList, SearchTeacherDTO searchTeacherDTO) {
        List<Integer> list = new ArrayList<>();
        for (Integer uid : uidList) {
            List<Integer> userFarvoriteSubjectIds = ustableService.getUserFarvoriteSubjectIds(uid);
            if (CollectionUtils.isEmpty(userFarvoriteSubjectIds)) {
                list.add(uid);
                continue;
            }
            List<Integer> subjectIds = searchTeacherDTO.getSubjectIds();
            for (int i = 0; i < subjectIds.size(); i++) {
                if (userFarvoriteSubjectIds.contains(subjectIds.get(i))) {
                    list.add(uid);
                    break;
                }
            }

        }
        List<Integer> collect = list.stream().distinct().collect(Collectors.toList());
        return collect;
    }


//    @Override
//    public IPage searchNameTeacher(SearchTeacherDTO searchDTO) {
//        String teacherName = searchDTO.getTeacherName();
//        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
//        queryWrapper.like("username", teacherName).or()
//                .like("real_name", teacherName);
//        IPage<User> page = new Page<>(searchDTO.getPage(), searchDTO.getSize());
//        page = userMapper.selectPage(page, queryWrapper);
//        return page;
//    }

//    /**
//     * 订单搜索
//     * 时间顺序搜索
//     * 年级科目搜索
//     * @param searchTeacherDTO
//     * @return
//     */
//    @Override
//    public IPage searchOrder(SearchTeacherDTO searchTeacherDTO) {
//
//        if(StringUtils.isEmpty(searchTeacherDTO.getParentName())) {
//            // 查询所有订单
//        }
////        模糊查询用户订单
//
//
//
//        // 查询未完成的订单
////        IPage<OrderTable> page = new Page<>(searchTeacherDTO.getPage(), searchTeacherDTO.getSize());
//        QueryWrapper<OrderTable> queryWrapper = new QueryWrapper<>();
//        queryWrapper
//                .eq("finished", 0)
////                .and(searchTeacherDTO.getOrderCreateTime() != null, i -> {
////                    return i.gt("create_time", searchTeacherDTO.getOrderCreateTime());
////                })
//                .and((searchTeacherDTO.getParentName() != null && searchTeacherDTO.getParentName().length() > 0), i -> {
//                    return i.like("username", searchTeacherDTO.getParentName())
//                            .or()
//                            .like("real_name",  searchTeacherDTO.getParentName());
//                })
//                .orderByDesc(searchTeacherDTO.getOrderCreateTime() != null, "create_time");
//
//        List<OrderTable> orderTables = orderTableMapper.selectList(queryWrapper);
//        List<OrderVO> orderVOList = MyBeanUtils.converToList(orderTables, OrderVO.class);
//        for (OrderVO orderVO : orderVOList) {
////            设置用户头像
//            String s1 = ossUtils.addUrlPrefix(userMapper.selectAvatarById(orderVO.getPid()));
//            orderVO.setAvatar(s1);
//        }
//
//        int total = orderTables.size();
//        int fromIndex = Math.toIntExact((searchTeacherDTO.getPage() - 1) * searchTeacherDTO.getSize());
//        int toIndex = Math.toIntExact(searchTeacherDTO.getPage() * searchTeacherDTO.getSize());
//
//        return null;
//    }

    /**
     * 获取家长感兴趣的教师
     *
     * @param dto
     * @return
     */
    @Override
    public IPage getFarvoriteTeacher(SearchTeacherDTO dto) {
        if (dto.getUid() == null) {
            return this.search(dto);
        }
        List<Integer> userFarvoriteGradeIds = ugtableService.getUserFarvoriteGradeIds(dto.getUid());
        List<Integer> userFarvoriteSubjectIds = ustableService.getUserFarvoriteSubjectIds(dto.getUid());
        dto.setGradeIds(userFarvoriteGradeIds);
        dto.setSubjectIds(userFarvoriteSubjectIds);
        IPage search = this.search(dto);
        return search;
    }

//    /**
//     * 订单搜索
//     * @param dto
//     * @return
//     */
//    @Override
//    public IPage searchOrder(SearchOrderDTO dto) {
//        // 条件过滤
//
//
//    }


    /**
     * 查询用户
     * @param dto
     * @return
     */
    @Override
    public IPage searchUser(SearchUserDTO dto) {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        if (dto.getRoleId() != null) {
            queryWrapper.eq("role_id", dto.getRoleId());
        } else {
            queryWrapper.ne("role_id", RoleEnum.ADMIN.getId());
        }
        if (dto.getUsername() != null) {
            queryWrapper.like("username", dto.getUsername());
        }
        IPage<User> page = userMapper.selectPage(new Page<>(dto.getPage(), dto.getSize()), queryWrapper);
        IPage<UserVO> result = new Page<>(dto.getPage(), dto.getSize());
        result.setTotal(page.getTotal())
                .setRecords(MyBeanUtils.converToList(page.getRecords(), UserVO.class))
                .setPages(page.getPages());
        if (!CollectionUtils.isEmpty(result.getRecords())) {
            setAvatar(result.getRecords());
            for (UserVO record : result.getRecords()) {
                Role role = roleMapper.selectById(record.getRoleId());
                record.setRole(role);
            }
        }
        return result;
    }
}
